#pragma once
#ifndef MAPPOINT_H
#define MAPPOINT_H

#include "common.h"

namespace myslam
{
    struct Frame;
    struct Feature;
    
    /**
     * 路标点类
     * 特征点在三角化之后形成路标点
     */
struct MapPoint
{
public:
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW;   //这个宏在new一个对象时会总是返回一个对齐的指针。
    typedef std::shared_ptr<MapPoint> Ptr;
    unsigned long id_=0;  //ID
    bool is_outlier_=false;
    Vec3 pos_=Vec3::Zero();  //Position in world
    std::mutex data_mutex_;
    int observed_times=0;    //being observed by feature matching algo.
    std::list<std::weak_ptr<Feature>> observations_;
    
    MapPoint() {}
    
    MapPoint(long id, Vec3 position);
    
    Vec3 Pos()
    {
        std::unique_lock<std::mutex> lck(data_mutex_);
        return pos_;
    }
    
    void SetPos(const Vec3 &pos)
    {
        std::unique_lock<std::mutex> lck(data_mutex_);
        pos_=pos;
    }
    
    void AddObservation(std::shared_ptr<Feature> feature)
    {
        std::unique_lock<std::mutex> lck(data_mutex_);
        observations_.push_back(feature);
        observed_times_++;
    }
    
    void RemoveObservation(std::shared_ptr<Feature> feat);
    
    std::list<std::weak_ptr<Feature>> GetObs()   //weak智能指针
    {
        std::unique_lock<std::mutex> lck(data_mutex_);
        return observations_;
    }
    
    //factory function 
    static MapPoint::Ptr CreateNewMappoint();
};

} //namespace myslam

#endif  //MYSLAM_MAPPOINT_H

